package tr.gov.tubitak.uekae.applet.ops;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tr.gov.tubitak.uekae.applet.resource.ResourceUtil;
import tr.gov.tubitak.uekae.esya.api.asn.x509.ECertificate;
import tr.gov.tubitak.uekae.esya.api.common.crypto.BaseSigner;
import tr.gov.tubitak.uekae.esya.api.common.util.Base64;
import tr.gov.tubitak.uekae.esya.api.signature.*;
import tr.gov.tubitak.uekae.esya.api.signature.config.ConfigurationException;
import tr.gov.tubitak.uekae.esya.api.signature.impl.SignableBytes;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Provides operations for new interface
 *
 * @author suleyman.uslu
 */
public class ContainerOps extends Ops {

    private static final Logger msLogger = LoggerFactory.getLogger(ContainerOps.class);

    /**
     * Determines format of signature to be created
     * Can be CAdES or XAdES
     */
    SignatureFormat signatureFormat;

    public ContainerOps(byte[] aContentBytes, ECertificate aCertificate, BaseSigner aBaseSigner, SignatureFormat aSignatureFormat) {

        super(aContentBytes, aCertificate, aBaseSigner);

        signatureFormat = aSignatureFormat;
    }

    /**
     * Creates signature with new signing interface, called from WebLoginApplet
     * @return signature as byte array
     */
    public String sign() {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            msLogger.debug("Starting signing process with new interface");

            SignatureContainer container = SignatureFactory.createContainer(signatureFormat, createContext(contentBytes));

            Signature signature = container.createSignature(certificate);

            signature.addContent(getContent(contentBytes), true);

            signature.sign(baseSigner);

            container.write(baos);

            msLogger.debug("Signature : " + new String(baos.toByteArray()));
            msLogger.debug("End of signing with new interface");
        }
        catch (Exception e) {
            msLogger.debug("error in sign with new interface");
        }

        return Base64.encode(baos.toByteArray());
    }

    public static Signable getContent(byte[] contentBytes) {

        return new SignableBytes(contentBytes, "data.txt", "text/plain");
    }

    /**
     * Creates context and sets data
     * @return created context
     */
    public static tr.gov.tubitak.uekae.esya.api.signature.Context createContext(byte[] contentBytes) throws ConfigurationException {

        msLogger.debug("Context is being created");
        tr.gov.tubitak.uekae.esya.api.signature.Context c = new tr.gov.tubitak.uekae.esya.api.signature.Context();
        msLogger.debug("Context has created");

        try {
            c.setConfig(ResourceUtil.getSignatureConfig());
        } catch (IOException e) {
            e.printStackTrace();
        }

        if(c != null) {
            msLogger.debug("Context is not null");

            if(c.getConfig() != null)
                msLogger.debug("Config is not null");
            else
                msLogger.debug("Config is null!");
        }
        else
            msLogger.debug("Context is null!");

        c.setData(getContent(contentBytes));
        return c;
    }
}
